package org.ws.httphelper.support.fetcher;

import org.ws.httphelper.core.fetcher.HttpFetcher;
import org.ws.httphelper.exception.FetchException;
import org.ws.httphelper.model.config.ClientConfig;
import org.ws.httphelper.model.http.RequestData;
import org.ws.httphelper.model.http.ResponseData;
import org.ws.httphelper.model.http.ResponseFuture;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

/**
 * 抽象的HttpFetcher/
 * 根据同步方法使用线程池实现了异步请求。
 */
public abstract class AbstractHttpFetcher implements HttpFetcher {

    /**
     * client配置
     */
    protected final ClientConfig clientConfig;
    /**
     * 异步线程池
     */
    private final ExecutorService executor;

    public AbstractHttpFetcher(ClientConfig clientConfig) {
        this.clientConfig = clientConfig;
        // TODO:自定义
        this.executor = Executors.newFixedThreadPool(clientConfig.getThreadNumber());
    }

    /**
     * 异步实现fetch
     * @param requestData 请求数据
     * @param callback 回调函数
     * @throws FetchException
     */
    @Override
    public void fetch(final RequestData requestData, Consumer<ResponseFuture> callback) throws FetchException {
        // 直接提交到线程池处理
        this.executor.execute(new Runnable() {
            @Override
            public void run() {
                // 回调
                ResponseFuture responseFuture = new ResponseFuture(requestData);
                try {
                    // 调用同步处理执行实际请求
                    ResponseData responseData = fetch(requestData);
                    responseFuture.setResponseData(responseData);
                    responseFuture.setSuccess(responseData.isSuccessful());
                } catch (FetchException e) {
                    // 执行异常情况
                    ResponseData responseData = new ResponseData();
                    responseData.setStatus(500);
                    responseFuture.setResponseData(responseData);
                    responseFuture.setSuccess(false);
                } finally {
                    // 无论成功失败都执行回调
                    callback.accept(responseFuture);
                }
            }
        });
    }

    /**
     * 通过contentType判断响应是否为String
     * @param contentType
     * @return
     */
    protected boolean isStringBody(String contentType){
        String type = contentType.toLowerCase();
        return (type.contains("text") || type.contains("json") || type.contains("xml"));
    }

}
